`timescale 1ns/1ns

//mixed-design for restoring division
module div_restoring (a, b, start, rslt);
//define inputs and outputs
input [7:0] a;
input [3:0] b;
input start;
output [7:0] rslt;

//define internal net
wire [3:0] b_bar;

//define internal registers
//variables used in always are declared as reg
reg [3:0] b_neg;
reg [7:0] rslt;
reg [3:0] count;

assign b_bar = ~b;

always @ (b_bar)
    b_neg = b_bar + 1;

reg cout;
reg [3:0] sum;

//execute the behavioral statements within the always block
always @ (posedge start) begin
    rslt = a;
    count = 4'b0100;
    if ((a!=0) && (b!=0)) begin 
        while (count) begin
            rslt = rslt << 1;
            {cout, sum} = rslt[7:4] + b_neg;
            rslt = { sum, rslt[3:0] };
            if(cout == 0) begin // 用cout来判断无符号减法是否溢出
                rslt = { (rslt[7:4] + b), rslt[3:1], 1'b0};
            end
            else begin 
                rslt = {rslt[7:1], 1'b1};
            end
            count = count - 1;
        end
    end
end

endmodule

//test bench for restoring division
module div_restoring_tb;
reg [7:0] a;
reg [3:0] b;
reg start;
wire [7:0] rslt;

//display variables
initial $monitor ("a = %d, b = %d, quot = %d, rem = %d", a, b, rslt[3:0], rslt[7:4]);

initial begin //apply input vectors 
    #0 start = 1'b0;
    a = 8'b0000_1101;
    b = 4'b0101;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0011_1100;
    b = 4'b0111;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0101_0010;
    b = 4'b0110;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0011_1000;
    b = 4'b0111;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0110_0100;
    b = 4'b0111;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0110_1110;
    b = 4'b0111;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0010_0101;
    b = 4'b0011;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0100_1000;
    b = 4'b0111;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0101_0100;
    b = 4'b0110;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0010_1110;
    b = 4'b0101;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0000_1111;
    b = 4'b1110;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0010_1111;
    b = 4'b1000;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 a = 8'b0110_1110;
    b = 4'b1011;
    #10 start = 1'b1;
    #10 start = 1'b0;
    #10 $finish;
end

div_restoring inst1 (a, b, start, rslt);//instantiate module

wire [3:0] quot = rslt[3:0];
wire [3:0] rem  = rslt[7:4];

initial begin
    $dumpfile("div_restoring_tb.vcd"); //生成的 vcd 文件名称
    $dumpvars(0, div_restoring_tb); //测试模块名称
end

endmodule
